package cc.admin.modules.message.websocket;

import cc.admin.common.constant.WebsocketConst;
import cc.admin.modules.monitor.service.ServerMonitorService;
import cc.admin.modules.monitor.service.impl.ServerMonitorServiceImpl;
import cc.admin.modules.sys.entity.SysUser;
import cc.admin.modules.sys.mapper.SysUserMapper;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArraySet;

/**
 * @Author scott
 * @Date 2019/11/29 9:41
 * @Description: 此注解相当于设置访问URL
 */
@Component
@Slf4j
@ServerEndpoint("/websocket/{userId}") //此注解相当于设置访问URL
public class WebSocket {

	private ServerMonitorService serverMonitorService = new ServerMonitorServiceImpl();

	private Session session;

	private static CopyOnWriteArraySet<WebSocket> webSockets = new CopyOnWriteArraySet<>();
	private static Map<String, Session> sessionPool = Maps.newHashMap();
	private static final String ASSISTANT="assistant";
	@Resource
	private SysUserMapper sysUserMapper;
	@OnOpen
	public void onOpen(Session session, @PathParam(value = "userId") String userId) {
		try {
			this.session = session;
			webSockets.add(this);
			sessionPool.put(userId, session);
			log.info("【websocket消息】有新的连接，总数为:"+webSockets.size());
		} catch (Exception e) {
		}
	}

	@OnClose
	public void onClose() {
		try {
			webSockets.remove(this);
			log.info("【WebSocket消息】连接断开，总数为:" + webSockets.size());
		} catch (Exception e) {
		}
	}

	@OnMessage
	public void onMessage(String message) {
		log.debug("【WebSocket消息】收到客户端消息:" + message);
		JSONObject obj = new JSONObject();
		if (WebsocketConst.MSG_SERVER_INFO.equals(message)) {
			//服务器监控信息
			obj.put(WebsocketConst.MSG_CMD, WebsocketConst.MSG_SERVER_INFO);
			//消息内容
			obj.put(WebsocketConst.MSG_TXT, serverMonitorService.getServerInfo());
		} else if (WebsocketConst.CMD_CHECK.equals(message)) {
			//业务类型
			obj.put(WebsocketConst.MSG_CMD, WebsocketConst.CMD_CHECK);
			//消息内容
			obj.put(WebsocketConst.MSG_TXT, "心跳响应");
		}
		session.getAsyncRemote().sendText(obj.toJSONString());
	}

	/**
	 * 此为广播消息
	 * @param message
	 */
	public void sendAllMessage(String message) {
		log.info("【websocket消息】广播消息:"+message);
		QueryWrapper queryWrapper = new QueryWrapper<SysUser>();
		queryWrapper.eq("del_flag", "0");
		List<SysUser> sysUserList = sysUserMapper.selectList(queryWrapper);
		JSONObject jsonObject=JSON.parseObject(message);
		String msgTxt=jsonObject.get("msgTxt").toString();
		if (!StringUtils.isEmpty(msgTxt)){
			for (SysUser sysUser :sysUserList){
				sendReboot(sysUser.getId(), message);
			}
		}
		for(WebSocket webSocket : webSockets) {
			try {
				if(webSocket.session.isOpen()) {
					webSocket.session.getAsyncRemote().sendText(message);
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 此为单点消息
	 * @param userId
	 * @param message
	 */
	public void sendOneMessage(String userId, String message) {
		Session session = sessionPool.get(userId);
		if(!ASSISTANT.equals(userId)){
			sendReboot(userId,message);
		}
		if (session != null&&session.isOpen()) {
			try {
				log.info("【WebSocket消息】 单点消息:"+message);
				session.getAsyncRemote().sendText(message);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
	public void sendReboot(String userId,String message){
		Session session = sessionPool.get(ASSISTANT);
		JSONObject jsonObject =  JSON.parseObject(message);
		JSONObject json = new JSONObject();
		if(ASSISTANT.equals(userId)){
			json.put("name", jsonObject.get("name").toString());
			json.put("content",jsonObject.get("content").toString());
		}else{
			String cmd=jsonObject.get("cmd").toString();
			SysUser sysUser=sysUserMapper.selectById(userId);
			json.put("name",sysUser.getRealname());
			if(cmd.equals("flow")){
				json.put("content",sysUser.getRealname()+",您好。"+jsonObject.get("content").toString());
			}else{
				JSONObject msgTxt=JSON.parseObject(jsonObject.get("msgTxt").toString());
				json.put("content", sysUser.getRealname()+",您好。"+StrUtil.unWrap(msgTxt.get("msgContent").toString(), "<p>", "</p>"));
			}
		}
		if (session != null&&session.isOpen()) {
			try {
				log.info("【WebSocket消息】 单点消息:"+json.toJSONString());
				session.getAsyncRemote().sendText(json.toJSONString());
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
	/**
	 * 此为单点消息(多人)
	 * @param userIds
	 * @param message
	 */
	public void sendMoreMessage(String[] userIds, String message) {
		for (String userId : userIds) {
			sendOneMessage(userId, message);
		}

	}

	public Boolean connectStatus(String userId){
		Session session = sessionPool.get(userId);
		if (session != null&&session.isOpen()){
			return true;
		}else{
			return false;
		}
	}

}
